#include <stdio.h>
#include "cs1237.h"

/**
 * @brief cs1237首次IO初始化（默认全输出）
 *
 */
static void cs1237_io_Init(uint8_t CLK, uint8_t DIO)
{
    /*默认先全是输出*/
    gpio_set_direction(DIO, GPIO_MODE_OUTPUT);
    gpio_set_direction(CLK, GPIO_MODE_OUTPUT);
}

/**
 * @brief 数据线配置为输出
 * 
 * @param DIO 
 */
static void cs1237_dio_outputMode(uint8_t DIO)
{
    gpio_set_direction(DIO, GPIO_MODE_OUTPUT); /*DIO设置输出模式*/
}

/**
 * @brief 数据线配置为上拉输入
 *
 * @param DIO 数据线IO
 */
static void cs1237_dio_inputMode(uint8_t DIO)
{
    gpio_set_direction(DIO, GPIO_MODE_INPUT);  /*DIO设置输入模式*/
    gpio_set_pull_mode(DIO, GPIO_PULLUP_ONLY); /*上拉*/
}

/**
 * @brief 一个脉冲周期
 *
 * @param CLK 时钟线
 * @param DIO 数据线
 */
static void cs1237_OneClock(uint8_t CLK, uint8_t DIO)
{
    gpio_set_level(CLK, 1);
    ets_delay_us(1);
    gpio_set_level(DIO, 1);
    gpio_set_level(CLK, 0);
    ets_delay_us(1);
}

/**
 * @brief cs1237初始化配置
 *
 * @param cs1237_dat 结构体属性
 * @param speed ADC输出速率
 * @param channel 通道选择
 * @param pga PGA选择
 * @param refout REF输出开关
 */
void cs1237_config(_cs1237 *cs1237_dat, uint8_t speed, uint8_t channel, uint8_t pga, uint8_t refout)
{
    /*首次初始化io*/
    cs1237_io_Init(cs1237_dat->clk, cs1237_dat->dio);

    uint8_t i = 0, dat = 0;
    uint16_t count_i = 0;

    dat = (refout << 6) | (speed << 4) | (pga << 2) | (channel);
    cs1237_dio_outputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->dio, 1);
    cs1237_dio_inputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->clk, 0);
    while (gpio_get_level(cs1237_dat->dio) == 1)
    {
        vTaskDelay(1);
        count_i++;
        if (count_i > 300)
        {
            cs1237_dio_outputMode(cs1237_dat->dio);
            gpio_set_level(cs1237_dat->dio, 1);
            gpio_set_level(cs1237_dat->clk, 1);
            return;
        }
    }
    for (i = 0; i < 29; i++)
    {
        gpio_set_level(cs1237_dat->clk, 1);
        ets_delay_us(1);
        gpio_set_level(cs1237_dat->clk, 0);
        ets_delay_us(1);
    }
    cs1237_dio_outputMode(cs1237_dat->dio);

    for (i = 0; i < 8; i++)
    {
        cs1237_OneClock(cs1237_dat->clk, cs1237_dat->dio);
    }

    for (i = 0; i < 8; i++) // 38 - 45个脉冲了，写8位数据
    {
        gpio_set_level(cs1237_dat->clk, 1); // CLK=1;
        ets_delay_us(1);
        if (dat & 0x80)
        {
            gpio_set_level(cs1237_dat->dio, 1); // OUT = 1
        }
        else
        {
            gpio_set_level(cs1237_dat->dio, 0);
        }
        dat <<= 1;
        gpio_set_level(cs1237_dat->clk, 0); // CLK=0;
        ets_delay_us(1);
    }
    gpio_set_level(cs1237_dat->dio, 1); // OUT = 1
    gpio_set_level(cs1237_dat->clk, 1); // CLK=1;
    ets_delay_us(1);
    gpio_set_level(cs1237_dat->clk, 0); // CLK=0;
    ets_delay_us(1);
}

/**
 * @brief test
 * 
 * @param cs1237_dat 
 * @return uint8_t 
 */
uint8_t config(_cs1237 *cs1237_dat)
{
    uint8_t i = 0, dat = 0;
    uint16_t count_i = 0;

    cs1237_dio_outputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->dio, 1);
    cs1237_dio_inputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->clk, 0);
    while (gpio_get_level(cs1237_dat->dio) == 1)
    {
        vTaskDelay(1);
        count_i++;
        if (count_i > 300)
        {
            cs1237_dio_outputMode(cs1237_dat->dio);
            gpio_set_level(cs1237_dat->clk, 1);
            gpio_set_level(cs1237_dat->dio, 1);
            return 0;
        }
    }
    for (i = 0; i < 29; i++)
    {
        gpio_set_level(cs1237_dat->clk, 1);
        ets_delay_us(1);
        gpio_set_level(cs1237_dat->clk, 0);
        ets_delay_us(1);
    }
    cs1237_dio_outputMode(cs1237_dat->dio);

    for (i = 0; i < 7; i++) /*30-36*/
    {
        cs1237_OneClock(cs1237_dat->clk, cs1237_dat->dio);
    }

    gpio_set_level(cs1237_dat->dio, 1);
    gpio_set_level(cs1237_dat->clk, 1);
    ets_delay_us(1);
    gpio_set_level(cs1237_dat->clk, 0);
    ets_delay_us(1); // 37

    dat = 0;
    cs1237_dio_inputMode(cs1237_dat->dio);
    for (i = 0; i < 8; i++)
    {
        gpio_set_level(cs1237_dat->clk, 1);
        ets_delay_us(1);
        gpio_set_level(cs1237_dat->clk, 0);
        ets_delay_us(1);

        dat <<= 1;
        if (gpio_get_level(cs1237_dat->dio) == 1)
        {
            dat++;
        }
    }
    gpio_set_level(cs1237_dat->clk, 1);
    ets_delay_us(1);
    gpio_set_level(cs1237_dat->clk, 0);
    ets_delay_us(1);

    cs1237_dio_outputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->dio, 1);

    return dat;
}

/**
 * @brief cs1237读取数据
 * 
 * @param cs1237_dat 结构体属性
 * @return int32_t (+MAX=8388607=7FFFFFH   --------   +MAX=-8388608=-800000H)
 */
int32_t cs1237_read(_cs1237 *cs1237_dat)
{
    uint8_t i = 0;
    uint32_t dat = 0;
    uint16_t count_i = 0;
    int32_t temp;

    cs1237_dio_outputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->dio, 1);
    cs1237_dio_inputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->clk, 0);
    while (gpio_get_level(cs1237_dat->dio) == 1)
    {
        vTaskDelay(1);
        count_i++;
        if (count_i > 300)
        {
            cs1237_dio_outputMode(cs1237_dat->dio);
            gpio_set_level(cs1237_dat->clk, 1);
            gpio_set_level(cs1237_dat->dio, 1);
            return 0;
        }
    }
    dat = 0;
    for (i = 0; i < 24; i++)
    {
        gpio_set_level(cs1237_dat->clk, 1);
        ets_delay_us(1);
        dat <<= 1;
        if (gpio_get_level(cs1237_dat->dio) == 1)
        {
            dat++;
        }
        gpio_set_level(cs1237_dat->clk, 0);
        ets_delay_us(1);
    }

    for (i = 0; i < 3; i++)
    {
        gpio_set_level(cs1237_dat->clk, 1);
        ets_delay_us(1);
        gpio_set_level(cs1237_dat->clk, 0);
        ets_delay_us(1);
    }
    cs1237_dio_outputMode(cs1237_dat->dio);
    gpio_set_level(cs1237_dat->dio, 1);

    if (dat & 0x00800000) // 判断是负数 最高位24位是符号位
    {
        temp = -(((~dat) & 0x007FFFFF) + 1); // 补码变源码
    }
    else
        temp = dat; // 正数的补码就是源码

    return temp;
}